package net.cardgame.orcalecard.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import net.cardgame.oraclecard.service.DownloadUnzipObject;
import net.cardgame.oraclecard.service.ServiceDownloadListener;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.io.ZipInputStream;
import net.lingala.zip4j.model.FileHeader;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;

/**
 * Lớp xử lý chung các vấn đề về File
 * 
 */
public class FileUtils {
	static double totalTime = 0;
	private ServiceDownloadListener listener;
	private DownloadUnzipObject downloadUnzipObject;
	private boolean cancel = false;

	public void stopUnzip() {
		cancel = true;
	}

	private synchronized void setPercentDownload(int percent) {
		downloadUnzipObject.setPercent(percent);
		synchronized (listener) {
			if (listener != null) {
				listener.onUpdateProgressListener(
						downloadUnzipObject.getPercent(),
						downloadUnzipObject.getPosition(),
						downloadUnzipObject.getDeckId());
			}
		}

	}

	public void registryUnzipListener(ServiceDownloadListener listener) {
		this.listener = listener;
	}

	public FileUtils() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * Mã hóa file
	 * 
	 * @param sourcePath
	 * @param destinationPath
	 * @throws IOException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeyException
	 */
	public static void encrypt(String sourcePath, String destinationPath)
			throws IOException, NoSuchAlgorithmException,
			NoSuchPaddingException, InvalidKeyException {
		// Here you read the cleartext.
		FileInputStream fis = new FileInputStream(sourcePath);
		// This stream write the encrypted text. This stream will be wrapped by
		// another stream.
		FileOutputStream fos = new FileOutputStream(destinationPath);

		// Length is 16 byte
		SecretKeySpec sks = new SecretKeySpec(
				ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
		// Create cipher
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE, sks);
		// Wrap the output stream
		CipherOutputStream cos = new CipherOutputStream(fos, cipher);
		// Write bytes
		int b;
		byte[] d = new byte[4096];
		while ((b = fis.read(d)) != -1) {
			cos.write(d, 0, b);
		}
		// Flush and close streams.
		cos.flush();
		cos.close();
		fis.close();
	}

	/**
	 * Giải mã file
	 * 
	 * @param sourcePath
	 * @param destinationPath
	 * @throws IOException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeyException
	 */
	public static void decrypt(String sourcePath, String destinationPath)
			throws IOException, NoSuchAlgorithmException,
			NoSuchPaddingException, InvalidKeyException {
		FileInputStream fis = new FileInputStream(sourcePath);

		FileOutputStream fos = new FileOutputStream(destinationPath);
		SecretKeySpec sks = new SecretKeySpec(
				ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.DECRYPT_MODE, sks);
		CipherInputStream cis = new CipherInputStream(fis, cipher);
		int b;
		byte[] d = new byte[4096];
		while ((b = cis.read(d)) != -1) {
			fos.write(d, 0, b);
		}
		fos.flush();
		fos.close();
		cis.close();
	}

	/**
	 * 
	 * Giải mã file thành byte[] để xử lý
	 * 
	 * @param sourcePath
	 * @param destinationPath
	 * @return
	 * @throws IOException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeyException
	 */
	public static byte[] decryptToByteArray(String sourcePath,
			String destinationPath) throws IOException,
			NoSuchAlgorithmException, NoSuchPaddingException,
			InvalidKeyException {
		FileInputStream fis = new FileInputStream(sourcePath);

		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		SecretKeySpec sks = new SecretKeySpec(
				ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.DECRYPT_MODE, sks);
		CipherInputStream cis = new CipherInputStream(fis, cipher);
		int b;
		byte[] d = new byte[4096];
		while ((b = cis.read(d)) != -1) {
			bos.write(d, 0, b);
		}
		bos.flush();
		cis.close();
		return bos.toByteArray();
	}

	public static byte[] testDecrytToByteArray(String sourcePath,
			String destinationPath) throws IOException,
			NoSuchAlgorithmException, NoSuchPaddingException,
			InvalidKeyException {
		FileInputStream fis = new FileInputStream(sourcePath);

		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		SecretKeySpec sks = new SecretKeySpec(
				ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.DECRYPT_MODE, sks);
		CipherInputStream cis = new CipherInputStream(fis, cipher);
		int b;
		byte[] d = new byte[4096];
		b = cis.read(d);
		cis.close();
		bos.write(d, 0, b);
		boolean firstByte = true;
		while ((b = fis.read(d)) != -1) {
			if (firstByte) {
				firstByte = false;
				continue;
			}
			bos.write(d, 0, b);
		}
		bos.flush();
		fis.close();
		return bos.toByteArray();
	}

	public static InputStream decrytToInputStream(String sourcePath) {
		try {
			return new ByteArrayInputStream(decryptToByteArray(sourcePath, ""));
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/* Checks if external storage is available for read and write */
	public static boolean isExternalStorageWritable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)) {
			return true;
		}
		return false;
	}

	/* Checks if external storage is available to at least read */
	public static boolean isExternalStorageReadable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)
				|| Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
			return true;
		}
		return false;
	}

	static final int FILE_IMAGE_RESIZE = 1;
	static final int FILE_IMAGE_UNZIP = 2;
	static final int FILE_TEXT = 3;

	int getFileType(String fileName, String strDeckId) {
		if (fileName.contains("txt"))
			return FILE_TEXT;
		else if (fileName.contains("c" + strDeckId)) {
			fileName = fileName.substring(3, 5);
			if (convertStringToNumber(fileName) > 0)
				return FILE_IMAGE_RESIZE;
			else
				return FILE_IMAGE_UNZIP;
		}
		return FILE_IMAGE_UNZIP;
	}

	int convertStringToNumber(String str) {
		try {
			int i = Integer.parseInt(str);
			return i;
		} catch (Exception ex) {
			return -1;
		}
	}

	void testEncryptInputStream(byte[] data, String pathOutput)
			throws NoSuchAlgorithmException, NoSuchPaddingException,
			InvalidKeyException, IOException {
		InputStream inStreamX = new ByteArrayInputStream(data);
		FileOutputStream fosX = new FileOutputStream(pathOutput);
		// Length is 16 byte
		SecretKeySpec sks = new SecretKeySpec(
				ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
		// Create cipher
		Cipher cipherX = Cipher.getInstance("AES");
		cipherX.init(Cipher.ENCRYPT_MODE, sks);
		// Wrap the output stream
		CipherOutputStream cosX = new CipherOutputStream(fosX, cipherX);
		// Writes bytes
		int b;
		byte[] d = new byte[4096];
		// boolean firstByte = true;
		while ((b = inStreamX.read(d)) != -1) {
			cosX.write(d, 0, b);
		}
		cosX.flush();
		cosX.close();
		inStreamX.close();
	}

	void testEncryptInputStream(ZipInputStream inputStream,
			FileOutputStream outputStream) throws NoSuchAlgorithmException,
			NoSuchPaddingException, InvalidKeyException, IOException {
		// Length is 16 byte
		SecretKeySpec sks = new SecretKeySpec(
				ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
		// Create cipher
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE, sks);
		// Wrap the output stream
		CipherOutputStream cos = new CipherOutputStream(outputStream, cipher);
		// Writes bytes
		int b;
		byte[] d = new byte[4096];
		while ((b = inputStream.read(d)) != -1) {
			cos.write(d, 0, b);
		}
		cos.flush();
		cos.close();
		inputStream.close();
	}

	public boolean unzipFile(DownloadUnzipObject object) {
		this.downloadUnzipObject = object;
		return unzipFile(object.getPathSaveFile(), object.getDeckId(),
				object.getPosition());
	}

	/**
	 * Create by hungcv
	 * 
	 * perform unzipFile, create images X/2, X/3 and encrypt file
	 * 
	 * @param path
	 *            path of zip file
	 * @param deckId
	 *            deckBeanId
	 * @return
	 */
	public boolean unzipFile(String path, int deckId, int position) {
		String strDeckId = deckId < 10 ? "0" + deckId : "" + deckId;
		String pathFolderUnzip = path.replaceAll(".zip", "");
		String pathX2 = pathFolderUnzip + "/X2";
		String pathX3 = pathFolderUnzip + "/X3";
		File dirX2 = new File(pathX2);
		File dirX3 = new File(pathX3);
		dirX2.mkdirs();
		dirX3.mkdirs();
		try {
			ZipFile zipFile = new ZipFile(path);
			// if Zip file is password protected then set the password
			if (zipFile.isEncrypted()) {
				zipFile.setPassword(ConstantValue.PASSWORD);
			}
			// Get a list of FileHeader. FileHeader is the header information
			// for all the files in the ZipFile
			List listFileHeader = zipFile.getFileHeaders();
			int size = listFileHeader.size();
			int cardNumber = 0;
			for (int i = 0; i < size; i++) {
				FileHeader fileHeader = (FileHeader) listFileHeader.get(i);
				if (fileHeader.isDirectory())
					continue;
				String fileName = fileHeader.getFileName();
				fileName = fileName.split("\\/")[1];
				if (getFileType(fileName, strDeckId) == FILE_IMAGE_RESIZE) {
					cardNumber++;
				}
			}
			int numberFileFinished = 0;
			for (int i = 0; i < size; i++) {
				if (cancel)
					return false;
				FileHeader fileHeader = (FileHeader) listFileHeader.get(i);
				if (fileHeader.isDirectory()) {
					continue;
				}
				String fileName = fileHeader.getFileName();
				fileName = fileName.split("\\/")[1];
				int typeFile = getFileType(fileName, strDeckId);
				if (typeFile != FILE_IMAGE_RESIZE) {
					// Utils.DLog("File Type", "FILE_ONLY_UNZIP");
					String pathFileJPG = pathFolderUnzip + "/en_" + fileName;
					ZipInputStream in = zipFile.getInputStream(fileHeader);
					FileOutputStream fosjpg = new FileOutputStream(pathFileJPG);
					// encypt file
					testEncryptInputStream(in, fosjpg);
				} else {
					// Utils.DLog("File Type", "FILE_IMAGE_RESIZE");
					String pathFileX = pathFolderUnzip + "/en_" + fileName;
					String pathFileX2 = pathX2 + "/en_" + fileName;
					String pathFileX3 = pathX3 + "/en_" + fileName;
					Bitmap bmpX = BitmapFactory.decodeStream(zipFile
							.getInputStream(fileHeader));
					ByteArrayOutputStream streamX = new ByteArrayOutputStream();
					bmpX.compress(Bitmap.CompressFormat.PNG, 0, streamX);
					byte[] byteArrayX = streamX.toByteArray();
					testEncryptInputStream(byteArrayX, pathFileX);
					//
					// Create image X2
					Bitmap bmpX2 = resizeBitmap(bmpX, 2);
					bmpX.recycle();
					ByteArrayOutputStream streamX2 = new ByteArrayOutputStream();
					bmpX2.compress(Bitmap.CompressFormat.PNG, 0, streamX2);
					byte[] byteArrayX2 = streamX2.toByteArray();
					testEncryptInputStream(byteArrayX2, pathFileX2);
					// Create image X3
					Bitmap bmpX3 = resizeBitmap(bmpX2, 4);
					bmpX2.recycle();
					ThreadCreateX3Image threadX3 = new ThreadCreateX3Image(
							bmpX3, pathFileX3);
					threadX3.start();
					numberFileFinished++;
					// report percent download
					if (downloadUnzipObject != null) {
						int percent = (int) (((float) numberFileFinished / (float) cardNumber) * 49);
						this.setPercentDownload(50 + percent);
					}
				}

			}
		} catch (ZipException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		if (downloadUnzipObject != null) {
			this.setPercentDownload(100);
		}
		File fileRoot = new File(path);
		fileRoot.delete();
		return true;
	}

	class ThreadCreateX3Image extends Thread {
		Bitmap bmp;
		String path;

		public ThreadCreateX3Image(Bitmap bmp, String path) {
			this.bmp = bmp;
			this.path = path;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				ByteArrayOutputStream arrayOs = new ByteArrayOutputStream();
				bmp.compress(Bitmap.CompressFormat.PNG, 0, arrayOs);
				bmp.recycle();
				byte[] byteArray = arrayOs.toByteArray();
				InputStream inStreamX = new ByteArrayInputStream(byteArray);
				FileOutputStream fosX = new FileOutputStream(path);
				// Length is 16 byte
				SecretKeySpec sks = new SecretKeySpec(
						ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
				// Create cipher
				Cipher cipherX = Cipher.getInstance("AES");
				cipherX.init(Cipher.ENCRYPT_MODE, sks);
				// Wrap the output stream
				CipherOutputStream cosX = new CipherOutputStream(fosX, cipherX);
				// Writes bytes
				int b;
				byte[] d = new byte[4096];
				// boolean firstByte = true;
				while ((b = inStreamX.read(d)) != -1) {
					cosX.write(d, 0, b);
				}
				cosX.flush();
				cosX.close();
				inStreamX.close();
				;
			} catch (Exception ex) {
			}
		}
	}

	/*
	 * Sau khi download xong file zip ve thuc hien xu ly: - Load tu dau toi cuoi
	 * file zip - Toi fileHeader nao: + Neu header la PNG: * Tao cac X2, X3 * Ma
	 * hoa cac X, X3, X2 * Ghi X, X2, X3 ra sdcard + Neu header la TXT: * ma hoa
	 * cac text file * ghi cac text file ra sdcard
	 */
	public boolean processFileZip(String pathFileZip) {
		String strDECKID = getDeckId(pathFileZip);

		String pathFolderUnzip = getFolder(pathFileZip) + "/Card_" + strDECKID;
		String pathFolderX2 = pathFolderUnzip + "/X2";
		String pathFolderX3 = pathFolderUnzip + "/X3";
		File dirX2 = new File(pathFolderX2);
		File dirX3 = new File(pathFolderX3);
		dirX2.mkdirs();
		dirX3.mkdirs();
		try {
			ZipFile zipFile = new ZipFile(pathFileZip);

			// if Zip file is password protected then set the password
			if (zipFile.isEncrypted()) {
				zipFile.setPassword(ConstantValue.PASSWORD);
			}

			// Get a list of FileHeader. FileHeader is the header information
			// for all the files in the ZipFile
			List listFileHeader = zipFile.getFileHeaders();
			// Loop through all the fileHeaders
			for (int i = 0; i < listFileHeader.size(); i++) {
				FileHeader fileHeader = (FileHeader) listFileHeader.get(i);

				// Checks if the file is a directory
				if (fileHeader.isDirectory()) {
					continue;
				}

				/*
				 * THUC HIEN XU LY FILE Background "*.jpg"
				 */
				boolean kJPG = filterFileHeader(fileHeader.getFileName(), "jpg");
				if (kJPG) {
					String nameFile = fileHeader.getFileName().split("\\/")[1];
					String pathFileJPG = pathFolderUnzip + "/en_" + nameFile;

					ZipInputStream in = zipFile.getInputStream(fileHeader);

					FileOutputStream fosjpg = new FileOutputStream(pathFileJPG);
					// Length is 16 byte
					SecretKeySpec sks = new SecretKeySpec(
							ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
					// Create cipher
					Cipher cipher = Cipher.getInstance("AES");
					cipher.init(Cipher.ENCRYPT_MODE, sks);
					// Wrap the output stream
					CipherOutputStream cos = new CipherOutputStream(fosjpg,
							cipher);
					// Write bytes
					int b;
					byte[] d = new byte[4096];
					while ((b = in.read(d)) != -1) {
						cos.write(d, 0, b);
					}
					// Flush and close streams.
					cos.flush();
					cos.close();
					in.close();
				}

				/*
				 * THUC HIEN XU LY CAC FILE *.txt
				 */
				boolean kTXT = filterFileHeader(fileHeader.getFileName(), "txt");
				if (kTXT) {
					String nameFile = fileHeader.getFileName().split("\\/")[1];
					String pathFileText = pathFolderUnzip + "/en_" + nameFile;

					ZipInputStream inputStream = zipFile
							.getInputStream(fileHeader);

					FileOutputStream fostext = new FileOutputStream(
							pathFileText);
					// Length is 16 byte
					SecretKeySpec sks = new SecretKeySpec(
							ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
					// Create cipher
					Cipher cipher = Cipher.getInstance("AES");
					cipher.init(Cipher.ENCRYPT_MODE, sks);
					// Wrap the output stream
					CipherOutputStream cos = new CipherOutputStream(fostext,
							cipher);
					// Write bytes
					int b;
					byte[] d = new byte[4096];
					while ((b = inputStream.read(d)) != -1) {
						cos.write(d, 0, b);
					}

					// Flush and close streams.
					cos.flush();
					cos.close();
					inputStream.close();
				}

				/*
				 * THUC HIEN XU LY CAC FILE *.png
				 */
				boolean kPNG = filterFileHeader(fileHeader.getFileName(), "png");
				if (kPNG) {
					String nameFile = fileHeader.getFileName().split("\\/")[1];
					String pathFileX = pathFolderUnzip + "/en_" + nameFile;
					String pathFileX2 = pathFolderX2 + "/en_" + nameFile;
					String pathFileX3 = pathFolderX3 + "/en_" + nameFile;

					// File fileX = new File("",
					// fileHeader.getFileName().split("\\/")[1]);

					Bitmap bmpX = BitmapFactory.decodeStream(zipFile
							.getInputStream(fileHeader));
					Bitmap bmpX2 = resizeBitmap(bmpX, 2);
					Bitmap bmpX3 = resizeBitmap(bmpX, 3);
					// convert bitmap -> byte array
					ByteArrayOutputStream streamX = new ByteArrayOutputStream();
					ByteArrayOutputStream streamX2 = new ByteArrayOutputStream();
					ByteArrayOutputStream streamX3 = new ByteArrayOutputStream();
					bmpX.compress(Bitmap.CompressFormat.PNG, 0, streamX);
					bmpX.recycle();
					bmpX2.compress(Bitmap.CompressFormat.PNG, 0, streamX2);
					bmpX2.recycle();
					bmpX3.compress(Bitmap.CompressFormat.PNG, 0, streamX3);
					bmpX3.recycle();
					byte[] byteArrayX = streamX.toByteArray();
					byte[] byteArrayX2 = streamX2.toByteArray();
					byte[] byteArrayX3 = streamX3.toByteArray();

					// convert byte array -> inputstream
					InputStream inStreamX = new ByteArrayInputStream(byteArrayX);
					InputStream inStreamX2 = new ByteArrayInputStream(
							byteArrayX2);
					InputStream inStreamX3 = new ByteArrayInputStream(
							byteArrayX3);

					FileOutputStream fosX = new FileOutputStream(pathFileX);
					FileOutputStream fosX2 = new FileOutputStream(pathFileX2);
					FileOutputStream fosX3 = new FileOutputStream(pathFileX3);
					// Length is 16 byte
					SecretKeySpec sks = new SecretKeySpec(
							ConstantValue.FILE_SECRET_KEY.getBytes(), "AES");
					// Create cipher
					Cipher cipherX = Cipher.getInstance("AES");
					Cipher cipherX2 = Cipher.getInstance("AES");
					Cipher cipherX3 = Cipher.getInstance("AES");
					cipherX.init(Cipher.ENCRYPT_MODE, sks);
					cipherX2.init(Cipher.ENCRYPT_MODE, sks);
					cipherX3.init(Cipher.ENCRYPT_MODE, sks);
					// Wrap the output stream
					CipherOutputStream cosX = new CipherOutputStream(fosX,
							cipherX);
					CipherOutputStream cosX2 = new CipherOutputStream(fosX2,
							cipherX2);
					CipherOutputStream cosX3 = new CipherOutputStream(fosX3,
							cipherX3);

					// Writes bytes
					int b;
					byte[] d = new byte[4096];

					while ((b = inStreamX.read(d)) != -1) {
						cosX.write(d, 0, b);
					}
					cosX.flush();
					cosX.close();
					inStreamX.close();

					while ((b = inStreamX2.read(d)) != -1) {
						cosX2.write(d, 0, b);
					}
					cosX2.flush();
					cosX2.close();
					inStreamX2.close();

					while ((b = inStreamX3.read(d)) != -1) {
						cosX3.write(d, 0, b);
					}
					cosX3.flush();
					cosX3.close();
					inStreamX3.close();
				}

				Log.d("Done extracting: ", fileHeader.getFileName());
			}
		} catch (ZipException e) {
			Log.e("ZipException", e.toString());
			return false;
		} catch (FileNotFoundException e) {
			Log.e("FileNotFoundException", e.toString());
			return false;
		} catch (IOException e) {
			Log.e("IOException", e.toString());
			return false;
		} catch (Exception e) {
			Log.e("Exception", e.toString());
			return false;
		}

		// Xoa file zip sau khi xu ly hoan thanh
		File f = new File(pathFileZip);
		f.delete();

		return true;
	}

	public boolean filterFileHeader(String fileHeader, String filter) {
		boolean check = false;
		String[] sub = fileHeader.split("\\.");
		String s = sub[1];
		if (s.equalsIgnoreCase(filter))
			check = true;

		return check;
	}

	// Nếu s = "/mnt/sdcard/testpass.zip"
	// Thì folderName = "/mnt/sdcard"
	public String getFolder(String s) {
		String folderName = "";
		for (int i = s.length() - 1; i >= 0; i--) {
			if (s.charAt(i) == '/') {
				folderName = s.substring(0, i);
				break;
			}
		}
		return folderName;
	}

	// Lấy về tất cả các file trong folder ung voi bo loc "filter"
	public ArrayList<String> getListFile(String pathFolder, String filter) {
		ArrayList<String> tmpList = new ArrayList<String>();
		ArrayList<String> list = new ArrayList<String>();
		File f = new File(pathFolder);

		// Kiểm tra folder tồn tại hay không
		// Hoặc có phải là thư mục hay không
		if (!f.exists() || !f.isDirectory()) {
			return null;
		}

		String[] files = f.list();
		if (files.length == 0) { // Không có file nào trong folder
			return null;
		}

		for (int i = 0; i < files.length; i++) {
			tmpList.add(files[i]);
		}

		for (int i = 0; i < tmpList.size(); i++) {
			String s = tmpList.get(i);
			String typeFile = s.substring(s.length() - 3, s.length());
			if (typeFile.equalsIgnoreCase(filter))
				list.add(s);
		}

		return list;
	}

	/*
	 * Resize lai kich thuoc bitmap
	 */
	public Bitmap resizeBitmap(Bitmap bmp, int i) {
		int width = 0, height = 0;
		switch (i) {
		case 2:
			width = bmp.getWidth() / 2;
			height = bmp.getHeight() / 2;
			break;
		case 3:
			width = bmp.getWidth() / 3;
			height = bmp.getHeight() / 3;
		case 4:
			width = (int) (bmp.getWidth() / 1.5);
			height = (int) (bmp.getHeight() / 1.5);
		default:
			break;
		}

		Bitmap resizedbitmap = Bitmap.createScaledBitmap(bmp, width, height,
				true);
		return resizedbitmap;
	}

	@SuppressWarnings("resource")
	public static byte[] getBytesFromFile(File file) throws IOException {
		InputStream is = new FileInputStream(file);

		// Get the size of the file
		long length = file.length();

		// You cannot create an array using a long type.
		// It needs to be an int type.
		// Before converting to an int type, check
		// to ensure that file is not larger than Integer.MAX_VALUE.
		if (length > Integer.MAX_VALUE) {
			// File is too large
		}

		// Create the byte array to hold the data
		byte[] bytes = new byte[(int) length];

		// Read in the bytes
		int offset = 0;
		int numRead = 0;
		while (offset < bytes.length
				&& (numRead = is.read(bytes, offset,
						Math.min(bytes.length - offset, 512 * 1024))) >= 0) {
			offset += numRead;
		}

		// Ensure all the bytes have been read in
		if (offset < bytes.length) {
			throw new IOException("Could not completely read file "
					+ file.getName());
		}

		// Close the input stream and return bytes
		is.close();
		return bytes;
	}

	// get deckId from path filezip
	public String getDeckId(String pathFileZip) {
		String subPath = "";
		String[] arr = null;

		arr = pathFileZip.split("\\/");
		subPath = arr[arr.length - 1];

		arr = subPath.split("\\_");
		subPath = arr[arr.length - 1];

		arr = subPath.split("\\.");
		subPath = arr[0];

		return subPath;
	}

	public static void CopyStream(InputStream is, OutputStream os) {
		final int buffer_size = 1024;
		try {
			byte[] bytes = new byte[buffer_size];
			for (;;) {
				int count = is.read(bytes, 0, buffer_size);
				if (count == -1)
					break;
				os.write(bytes, 0, count);
			}
		} catch (Exception ex) {
		}
	}

	public static Bitmap createReflectedImage(Bitmap b) {
		final int reflectionGap = 10;

		Bitmap originalImage = b;

		int width = originalImage.getWidth();
		int height = originalImage.getHeight();

		Matrix matrix = new Matrix();
		matrix.preScale(1, -1);

		Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
				height / 2, width, height / 2, matrix, false);

		Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
				(height + height / 2), Config.ARGB_8888);

		Canvas canvas = new Canvas(bitmapWithReflection);

		canvas.drawBitmap(originalImage, 0, 0, null);

		// Paint deafaultPaint = new Paint();
		// canvas.drawRect(0, height, width, height + reflectionGap,
		// deafaultPaint);

		canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);

		Paint paint = new Paint();
		LinearGradient shader = new LinearGradient(0,
				originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
						+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);

		paint.setShader(shader);

		paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));

		canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
				+ reflectionGap, paint);
		return bitmapWithReflection;
	}

	/**
	 * @param downloadsize
	 *            byte
	 * @return true: SDCARD available
	 * 
	 * <br>
	 *         false:SDCARD unvailable
	 */
	public static boolean availableDownload(double downloadsize) {
		StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
				.getPath());
		double sdAvailSize = (double) stat.getAvailableBlocks()
				* (double) stat.getBlockSize();
		return sdAvailSize > 3 * downloadsize;
	}
}
